/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ChatNI;

import common.Bye;
import common.*;
import common.Hello;
import common.Message;
import common.Fichier;
import common.Text;
import common.TransfertFileAccept;
import MVC.*;
import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.LinkedList;
import java.util.Observable;

/**
 * UDPcom
 * Class in charge of sending the file via UDP
 * It's a View of the ModelMessOut
 * @author Duy Duc, Metangmo
 */
public class UDPcom extends ChatNI implements java.util.Observer{
    
    private java.net.DatagramSocket ds;
    private InetAddress destination;
    private final int destPort;
    private final static int size = 1000;
    private int phase=0;
    private ListenUDP udp;
    public LinkedList<Message> fileMessage ;
    
    // MVC 
    private ChatController controller;

    
    
    

    
    /**
     * Constructor
     * @param port
     *        Port for receiving messages via UDP
     * @param destination
     *        IP Address of the recipient
     * @param destPort
     *        Port for sending messages via UDP
     * @param UDPThreads
     *        Instance of the ListenUDP
     * @param controller
     *        Instance of the ChatController
     * @param fileMessage
     *        Queue storing the received message waiting for being treated
     * @throws SocketException 
     */
    public UDPcom(int port,InetAddress destination, int destPort , ListenUDP UDPThreads , ChatController controller ,LinkedList<Message> fileMessage )throws SocketException {
        this.fileMessage = fileMessage;
        ds = new DatagramSocket(port);
        this.destination = destination;
        this.destPort = destPort;
        this.controller = controller;
        UDPThreads = new ListenUDP(ds,controller,this.fileMessage);
        this.udp = UDPThreads;
        UDPThreads.start();

    }

    
    /**
     * sendMess:
     * function sends the built messages to the recipient
     * @param mess
     *        Sent message
     * @param destination2
     *        IP Address of the recipient
     */
    public void sendMess(Message mess , InetAddress destination2) {

        try {
            
             // Destination of the packet
             this.destination = destination2;
            
             ByteArrayOutputStream baos = new ByteArrayOutputStream();
             ObjectOutputStream oos = new ObjectOutputStream(baos);
             oos.writeObject(mess);        
             oos.flush();
             byte[] data = baos.toByteArray();
             DatagramPacket dp = new DatagramPacket(data, data.length, destination, destPort);
             ds.send(dp);
             System.out.println("DatagramPacket is sent!!");
            
        } catch (Exception e) {
            System.out.println("Error sending datagram!!");
        }

    }
    

    /**
     * stop
     * function stops the execution of the UDP's threads
     * when the button Disconnection of ChatGUI is called
     */
    public void stop() {
         
        udp.interrupt(); 
        // The socket is closed
        ds.close();
    }

    
    /**
     * update:
     * function receives the update from the ModelMessOut and acts depending on the received information
     * @param o
     *        Model observed by TCPcom which is the ModelMessOut
     * @param obj
     *        Sent object from the ModelMessOut to UDPcom  
     */
    @Override
    public void update(Observable o, Object obj) {
        Message obj2;
        
        //Phase 0: TCPcom collects the recipient's IP Address from the ModelMessOut
        if(phase == 0){
            this.destination = (InetAddress)obj;
            phase =1;
            
        }
        //Phase 1: UDPcom collects from the ModelMessOut the message for sending to the recipient
        else{
            if (obj instanceof Fichier){
                System.out.println("Transfert de fichier");
            }
            else {
                obj2 = (Message)obj;
                System.out.println("Addr dest = " +this.destination);
                this.sendMess(obj2,this.destination);
            }
            phase=0;
        }
    }

    
    @Override
    public Message receive() {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }
    
    @Override
    public void send(Message message) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }
}